import { draw, dwm, process, winuser } from "easywin";
import { RECT } from "easywin/types/winuser";
export let filterP = new Set(['System', 'csrss.exe', 'wininit.exe'])


export interface WindowListItem {
  hWnd: number,
  title: string,
  classname: string,
  processId: number,
  threadId: number,
  exeFile: string,
  threads: number,
  Hicon: number,
  [index: string]: string | number
}
export function GetWinList({ visible = true, rmBlanktitle = true } = {}) {
  let temp = {}, tree = {}, _exp = { Id: 0, threads: 0 };
  process.ProcessSnapshot_cb((p) => {
    //保存资源管理器ID
    if (p.ExeFile === 'explorer.exe') {
      //避免出现伪装导致识别失败
      if (p.cntThreads > _exp.threads) {
        _exp.Id = p.Id
        _exp.threads = p.cntThreads
      }
    }
    temp[p.Id] = p;
  })
  //进程树
  for (let i in temp) {
    if (temp[i].ParentId && temp[temp[i].ParentId]) {
      if (!temp[temp[i].ParentId].children) {
        temp[temp[i].ParentId].children = new Object();
      }
      temp[temp[i].ParentId].children[temp[i].Id] = temp[i];
    }
    else {
      //过滤系统进程
      if (!filterP.has(temp[i].ExeFile)) {
        tree[temp[i].Id] = temp[i];
      }
    }
  }
  //删除系统空闲进程,Id:0
  delete tree[0]
  temp = null
  //展开树，用于窗口识别分类
  let flatTree = flat(tree)
  //枚举窗口
  let wins = winuser.EnumWindows()
  let result = { expWins: [], appWins: [] } as {
    expWins: WindowListItem[]
    appWins: WindowListItem[]
  }
  if (wins) {
    for (let i = 0; i < wins.length; i++) {
      const hWnd = wins[i];
      let _visible = winuser.IsWindowVisible(hWnd)
      if (visible) {
        if (!_visible) continue
      }
      let _title = winuser.GetWindowText(hWnd)
      if (rmBlanktitle) {
        if (_title === '') continue
      }

      let { ProcessId, ThreadId } = winuser.GetWindowThreadProcessId(hWnd)
      let _class = winuser.GetClassName(hWnd)
      if (flatTree.has(ProcessId)) {
        let _p = flatTree.get(ProcessId)
        if (_exp.Id === ProcessId) {
          result.expWins.push({
            hWnd: hWnd,
            title: _title,
            classname: _class,
            processId: ProcessId,
            threadId: ThreadId,
            exeFile: _p.ExeFile,
            threads: _p.cntThreads,
            Hicon: winuser.GetWindowHicon(hWnd)
          })
        } else {
          //APP只保留主窗口
          if (winuser.GetWindow(hWnd, 4) != 0) continue;
          result.appWins.push({
            hWnd: hWnd,
            title: _title,
            classname: _class,
            processId: ProcessId,
            threadId: ThreadId,
            exeFile: _p.ExeFile,
            threads: _p.cntThreads,
            Hicon: winuser.GetWindowHicon(hWnd)
          })
        }
      }
    }
  }
  return result
}

function flat(ps) {
  let result = new Map()
  function _recursion(_ps) {
    for (let key of Object.keys(_ps)) {
      if (_ps[key].children) {
        _recursion(_ps[key].children)
      }
      result.set(_ps[key].Id, _ps[key])
    }
  }
  _recursion(ps)
  return result;
}

